'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const config = {
    coins: [
        [6000, 7000, 8000],
        [2000, 3000, 4000],
        [2000, 6000, 7000],
        [3000, 8000, 10000],
        [4000, 7000, 8000],
        [5000, 6000, 7000],
        [9000, 10000, 13000],
        [9000, 11000, 20000],
        [8000, 12000, 13000],
        [8000, 12000, 13000],
    ]
};

// 具体状态类
class ConcreteClickCoin {
    constructor() {
        this.frameClock = null;
    }
    handle(context) {
        if (context.stepIndex >= 10) {
            context.setState(new ConcreteGameEnd());
        }
        else {
            //  设置玩家状态和金币状态，接受玩家选择数据，10s切换到pk状态
            context.game.sendPKData();
            this.frameClock = setInterval(() => {
                clearInterval(this.frameClock);
                context.setState(new ConcreteAniPK());
                context.request();
            }, 10000);
        }
    }
}
class ConcreteAniPK {
    constructor() {
        this.frameClock = null;
    }
    handle(context) {
        //  设置PK状态，并发送pk数据，10s切换到click状态
        context.game.sendPKResult();
        this.frameClock = setInterval(() => {
            // 计算结果
            context.game.resertSlickData();
            clearInterval(this.frameClock);
            context.stepIndex++;
            context.setState(new ConcreteClickCoin());
            context.request();
        }, 10000);
    }
}
class ConcreteGameEnd {
    constructor() {
        this.frameClock = null;
    }
    handle(context) {
        context.setState(null);
    }
}
var ConcreteState = {
    ConcreteClickCoin,
    ConcreteAniPK,
    ConcreteGameEnd
};

// 上下文类
class Context {
    constructor(args, game) {
        this.state = new ConcreteState.ConcreteClickCoin();
        this.args = args;
        this.stepIndex = 0;
        this.game = game;
    }
    sendData(data) {
        this.args.SDK.sendData(data).then().catch(err => {
            this.args.SDK.log.error('send Collide fail, roomId:' + this.args.roomId + 'err:' + err);
        });
    }
    setState(state) {
        this.state = state;
    }
    request() {
        var _a;
        (_a = this.state) === null || _a === void 0 ? void 0 : _a.handle(this);
    }
}

class Game {
    constructor(gameInitInfo, logger, frameRate, roomId) {
        this.frameClock = null;
        this.index = 0;
        this.gameContext = null;
        this.coinSlickMap = new Map();
        this.gameInitInfo = gameInitInfo;
        this.logger = logger;
        this.frameRate = frameRate;
        this.roomId = roomId;
    }
    /**
     * 初始化玩家
     * @param playerInfo 玩家信息
     */
    initPlayer(playerInfo) {
        for (let i = 0; i < this.gameInitInfo.playerArr.length; i++) {
            if (this.gameInitInfo.playerArr[i].playerId === playerInfo.playerId) {
                return;
            }
        }
        let data = {
            playerId: playerInfo.playerId,
            seatIndex: this.gameInitInfo.playerArr.length,
            coin: 0,
            waitCoin: 0
        };
        this.gameInitInfo.playerArr.push(data);
    }
    joinPlaer(playerInfo) {
        for (let i = 0; i < this.gameInitInfo.playerArr.length; i++) {
            if (this.gameInitInfo.playerArr[i].playerId === playerInfo.playerId) {
                return;
            }
        }
        let data = {
            playerId: playerInfo.playerId,
            seatIndex: this.gameInitInfo.playerArr.length,
            coin: 0,
            waitCoin: 0
        };
        this.gameInitInfo.playerArr.push(data);
        this.sendRoomData();
    }
    leavePlayer(playerInfo) {
        for (let i = 0; i < this.gameInitInfo.playerArr.length; i++) {
            if (this.gameInitInfo.playerArr[i].playerId === playerInfo.playerId) {
                this.gameInitInfo.playerArr.splice(i, 1);
                break;
            }
        }
        this.sendRoomData();
    }
    getPlayers() {
        return this.gameInitInfo.playerArr;
    }
    startGame(args) {
        this.startFrameClock(args);
        this.sendRoomData();
        return;
    }
    setPlayerSlick(playerId, slickIndx, args) {
        try {
            let player = this.gameInitInfo.playerArr.find(player => player.playerId === playerId);
            if (player === undefined) {
                this.SendData(args, JSON.stringify({ type: 'Toast', data: "玩家已不再房间" + args.roomId }));
                return;
            }
            if (player.isSlick) {
                this.SendData(args, JSON.stringify({ type: 'Toast', data: "玩家已经选择无法更改" }, [playerId]));
                return;
            }
            player.isSlick = true;
            let playerArr = this.coinSlickMap.get(slickIndx);
            if (playerArr) {
                this.coinSlickMap.set(slickIndx, playerArr.concat(playerId));
            }
            else {
                this.coinSlickMap.set(slickIndx, [playerId]);
            }
            this.sendRoomData();
        }
        catch (error) {
        }
    }
    getSlickResults() {
        return Object.fromEntries(this.coinSlickMap);
    }
    resertSlickData() {
        // 遍历 coinSlickMap
        this.coinSlickMap.forEach((playerIds, coinIndex) => {
            var _a, _b;
            if (playerIds.length == 1) {
                const player = this.gameInitInfo.playerArr.find(p => p.playerId === playerIds[0]);
                if (player) {
                    // 给玩家的 coin 属性增加奖励数量
                    player.coin += config.coins[((_a = this.gameContext) === null || _a === void 0 ? void 0 : _a.stepIndex) ? (_b = this.gameContext) === null || _b === void 0 ? void 0 : _b.stepIndex : 0][coinIndex];
                }
            }
            this.gameInitInfo.playerArr.forEach(player => {
                player.isSlick = false;
            });
        });
        this.coinSlickMap = new Map();
    }
    /**
     * 启动帧时钟
     * @param args 动作参数
     */
    startFrameClock(args) {
        if (this.gameContext !== null) {
            return;
        }
        this.gameContext = new Context(args, this);
        this.SendData(args, JSON.stringify({ type: 'Toast', data: "startFrameClock" + args.roomId }));
        this.gameContext.request();
        // args.SDK.log.info('startFrameClock' + this.roomId);
        // if (this.frameClock !== null) return;
        // this.frameClock = setInterval(() => {
        //     this.index++;
        //     let gameData: GameData = { type: 'InitGame', data: "success,回合:" + this.index };
        //     args.SDK.sendData(JSON.stringify(gameData)).then().catch(err => {
        //         args.SDK.log.error('send Collide fail, roomId:' + this.roomId + 'err:' + err);
        //     });
        // }, 10000);
    }
    stopFrameClock(args) {
        args.SDK.log.info('stopFrameClock' + this.roomId);
        clearInterval(this.frameClock);
        this.frameClock = null;
    }
    SendData(args, data, players) {
        // 广播游戏进度
        args.SDK.sendData(data, players).then().catch(err => {
            args.SDK.log.error('Toast' + err);
        });
    }
    //////////////////////发送客户端//////////
    sendRoomData() {
        var _a;
        let gameData = { type: 'RoomInfo', data: JSON.stringify(this.gameInitInfo) };
        (_a = this.gameContext) === null || _a === void 0 ? void 0 : _a.sendData(JSON.stringify(gameData));
    }
    sendPKData() {
        var _a, _b, _c;
        this.gameInitInfo.type = "Pk";
        this.gameInitInfo.coinData = config.coins[((_a = this.gameContext) === null || _a === void 0 ? void 0 : _a.stepIndex) ? (_b = this.gameContext) === null || _b === void 0 ? void 0 : _b.stepIndex : 0];
        this.gameInitInfo.endTime = Date.now() + 10000;
        this.gameInitInfo.pkResult = this.getSlickResults();
        let gameData = { type: 'Pk', data: JSON.stringify(this.gameInitInfo) };
        (_c = this.gameContext) === null || _c === void 0 ? void 0 : _c.sendData(JSON.stringify(gameData));
    }
    sendPKResult() {
        var _a, _b, _c, _d, _e;
        this.gameInitInfo.type = "PKResult";
        this.gameInitInfo.coinData = config.coins[((_a = this.gameContext) === null || _a === void 0 ? void 0 : _a.stepIndex) ? (_b = this.gameContext) === null || _b === void 0 ? void 0 : _b.stepIndex : 0];
        this.gameInitInfo.stepIndex = ((_c = this.gameContext) === null || _c === void 0 ? void 0 : _c.stepIndex) ? (_d = this.gameContext) === null || _d === void 0 ? void 0 : _d.stepIndex : 0;
        this.gameInitInfo.endTime = Date.now() + 10000;
        this.gameInitInfo.pkResult = this.getSlickResults();
        let gameData = { type: 'PKResult', data: JSON.stringify(this.gameInitInfo) };
        (_e = this.gameContext) === null || _e === void 0 ? void 0 : _e.sendData(JSON.stringify(gameData));
    }
}

// 定义 GameManage 类
class GameManage {
    constructor() {
        this.games = new Map();
    }
    saveGame(roomId, game) {
        this.games.set(roomId, game);
    }
    getGame(roomId) {
        return this.games.get(roomId);
    }
    removeGame(roomId) {
        this.games.delete(roomId);
    }
}
var GameManage$1 = new GameManage();

const gameServer = {
    onDestroyRoom(args) {
        // do something
        let game = GameManage$1.getGame(args.roomId);
        if (game === undefined) {
            args.SDK.log.error('onDestroyRoom game not exist' + args.roomId);
            return;
        }
        game.stopFrameClock(args);
        GameManage$1.removeGame(args.roomId);
    },
    onCreateRoom(args) {
        args.SDK.getRoomInfo().then(rommInfo => {
            args.SDK.log.error('onCreateRoom ' + rommInfo.roomStatus);
            args.SDK.log.error('onCreateRoom ' + rommInfo.roomCode);
            args.SDK.log.error('onCreateRoom ' + rommInfo.players.length);
            // 获取房间信息成功
        }).catch(err => {
            args.SDK.log.error('onCreateRoom ' + err);
            // 获取房间信息失败
        });
    },
    onRealTimeServerConnected(args) {
        // do something
    },
    onRealTimeServerDisconnected(args) {
        // do something
    },
    onConnect(args) {
        // do something
    },
    onDisconnect(args) {
        // do something
    },
    onJoin(playerInfo, args) {
        let game = GameManage$1.getGame(args.roomId);
        if (game === undefined) {
            return;
        }
        args.SDK.log.error('onJoin ' + playerInfo.playerId);
        game.joinPlaer(playerInfo);
        // do something
    },
    onLeave(playerInfo, args) {
        let game = GameManage$1.getGame(args.roomId);
        if (game === undefined) {
            return;
        }
        args.SDK.log.error('onLeave ' + playerInfo.playerId);
        game.leavePlayer(playerInfo);
        // do something
    },
    onRecvFrame(msg, args) {
        let unhandleFrames = Array.isArray(msg) ? msg : [msg];
        unhandleFrames.forEach(message => {
            // seed frames which do not have user data
            if (!message.frameInfo || message.frameInfo.length < 1) {
                return;
            }
            // frames which have user data
            message.frameInfo.forEach((frameData) => {
                let frameDataList = frameData.data;
                if (frameDataList && frameDataList.length > 0) {
                    frameDataList.forEach(res => {
                        args.SDK.log.info('frameData=' + res);
                    });
                }
            });
        });
    },
    // onRecvFromClient(args: GOBERTS.ActionArgs): void {
    //     args.SDK.getCache('example').then(value => {
    //         // 获取缓存成功
    //     }).catch(err => {
    //         // 获取缓存失败
    //     });
    // },
    onRecvFromClientV2(msg, args) {
        // do something, onRecvFromClientV2和onRecvFromClient使用一个即可，推荐使用V2
        let gameData = JSON.parse(msg.msg);
        switch (gameData.type) {
            case "InitGame":
                handleInitGame(gameData, args);
                break;
            case "StartGame":
                handleStartGame(gameData, args);
                break;
            case "Progress":
                handleProgress(gameData, args);
                break;
            case "SlickBox":
                handleSlickCoin(msg.srcPlayer, gameData.coinIndex, args);
                break;
        }
    },
    onRoomPropertiesChange(msg, args) {
        // do something
    },
    onStartFrameSync(args) {
        // do something
    },
    onStopFrameSync(args) {
        // do something
    },
    onUpdateCustomProperties(player, args) {
        // do something
    },
    onUpdateCustomStatus(msg, args) {
        // do something
    },
    onRequestFrameError(error, args) {
        // do something
    },
    onRoomPropertiesChangeFailed(error, args) {
        // do something
    },
    onInstantMessageFailed(error, args) {
        // do something
    },
};
const gobeDeveloperCode = {
    gameServer: gameServer,
    appId: 'your appId',
};
/**
 * 处理游戏初始化
 * @param gameData
 * @param args
 */
function handleInitGame(gameData, args) {
    // 初始化游戏信息，并以房间维度保存
    let gameInitInfo = gameData;
    if (GameManage$1.getGame(args.roomId) !== undefined) {
        // 广播游戏进度
        Toast(args, JSON.stringify({ type: 'Toast', data: "房间已初始化" }));
        return;
    }
    let game = new Game(gameInitInfo, args.SDK.log, 30, args.roomId);
    GameManage$1.saveGame(args.roomId, game);
    args.SDK.getRoomInfo().then(rommInfo => {
        // 获取房间信息成功
        for (let i = 0; i < rommInfo.players.length; i++) {
            game.initPlayer(rommInfo.players[i]);
        }
    });
}
function handleStartGame(gameData, args) {
    let game = GameManage$1.getGame(args.roomId);
    if (game === undefined) {
        args.SDK.log.error('onStartGame game not exist' + args.roomId);
        return;
    }
    game.startGame(args);
}
/**
 * 处理加载进度
 * @param gameData
 * @param args
 */
function handleProgress(gameData, args) {
    // 广播游戏进度
    args.SDK.sendData(JSON.stringify(gameData)).then().catch(err => {
        args.SDK.log.error('sendProgressData ERROR' + err);
    });
}
/**
 * 玩家选择金币
 * @param gameData
 * @param args
 */
function handleSlickCoin(playerId, coinIdex, args) {
    let game = GameManage$1.getGame(args.roomId);
    if (game === undefined) {
        return;
    }
    game.setPlayerSlick(playerId, coinIdex, args);
}
function Toast(args, data) {
    // 广播游戏进度
    args.SDK.sendData(data).then().catch(err => {
        args.SDK.log.error('Toast' + err);
    });
}

exports.gobeDeveloperCode = gobeDeveloperCode;
